package com.demo.java.concurrent.thread;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class GuardedSuspensionTest {
    public static void main(String[] args) throws InterruptedException {
        GuardedObject<String> guardedObject = new GuardedObject();
        new Thread(() -> {
            String obj = guardedObject.get();
            log.info("guarded obj: " + obj);
        }, "t1").start();
        new Thread(() -> {
            try {
                log.info("do some business");
                Thread.sleep(10000);
            } catch (InterruptedException e) {}
            guardedObject.complete("hello");
        }, "t2").start();
        Thread.sleep(15000);
    }
}

@Slf4j
class GuardedObject<T> {
    private T obj;
    public T get() {
        // 1. 临界资源保护，保证共享资源在多线程下可见，作用类似volatile
        // 2. wait方法需要一个监视器对象
        synchronized (this) {
            while (obj == null) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    log.info("===== wait interrupted.", e);
                }
            }
        }
        return this.obj;
    }
    public void complete(T obj) {
        synchronized (this) {
            this.obj = obj;
            this.notifyAll();
        }
    }
}
